package com.lishui.waterojbackendquestionservice.controller;

import com.lishui.waterojbackendmodel.model.annotation.AuthCheck;
import com.lishui.waterojbackendmodel.model.annotation.JudgeEmpty;
import com.lishui.waterojbackendcommon.contant.MessageConstant;
import com.lishui.waterojbackendcommon.contant.UserConstant;
import com.lishui.waterojbackendcommon.exception.BusinessException;
import com.lishui.waterojbackendcommon.exception.ParameterException;
import com.lishui.waterojbackendcommon.result.PageResult;
import com.lishui.waterojbackendcommon.result.Result;
import com.lishui.waterojbackendmodel.model.enumeration.OperationTypeEnum;
import com.lishui.waterojbackendmodel.model.pojo.dto.*;
import com.lishui.waterojbackendmodel.model.pojo.entity.Question;
import com.lishui.waterojbackendmodel.model.pojo.vo.QuestionVO;
import com.lishui.waterojbackendmodel.model.pojo.vo.UserVO;
import com.lishui.waterojbackendquestionservice.service.QuestionService;
import com.lishui.waterojbackendquestionservice.service.QuestionSubmitService;
import com.lishui.waterojbackendserviceclient.service.UserFeignClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import com.lishui.waterojbackendmodel.model.pojo.dto.QuestionAddDTO;
import com.lishui.waterojbackendmodel.model.pojo.dto.QuestionQueryDTO;
import com.lishui.waterojbackendmodel.model.pojo.dto.QuestionUpdateDTO;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping
@Slf4j
@Api(tags = "题目相关接口")
public class QuestionController {
    @Resource
    private QuestionService questionService;

    @Resource
    private QuestionSubmitService questionSubmitService;

    @Resource
    private UserFeignClient userFeignClient;


    @PostMapping
    @ApiOperation("添加题目")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<Long> addQuestion(@RequestBody QuestionAddDTO questionAddDTO, HttpServletRequest httpServletRequest) {
        Long questionId = questionService.addQuestion(questionAddDTO, httpServletRequest);
        return Result.success(questionId);
    }

    /**
     * 删除
     */
    @DeleteMapping("/{id}}")
    @ApiOperation("删除题目")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result deleteQuestionById(@PathVariable Long id, HttpServletRequest httpServletRequest) {
        if (id <= 0) {
            throw new BusinessException(MessageConstant.ERROR_PARAMETER + ":id不能小于等于0");
        }
        questionService.deleteQuestionById(id, httpServletRequest);
        return Result.success();
    }

    @PutMapping("/update")
    @ApiOperation("管理员修改题目")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result updateQuestion(@RequestBody QuestionUpdateDTO questionUpdateDTO) {
        questionService.updateQuestion(questionUpdateDTO);
        return Result.success();
    }

    @PutMapping("/edit")
    @ApiOperation("出题人编辑题目")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result editQuestion(@RequestBody QuestionEditDTO questionEditDTO, HttpServletRequest httpServletRequest) {
        Long questionId = questionEditDTO.getId();
        Question oldQuestion = questionService.getById(questionId);
        if (oldQuestion == null) throw new BusinessException(MessageConstant.NO_EXISTS + ":question");
        UserVO currentUser = userFeignClient.getCurrentUser(httpServletRequest);
        // 仅本人或管理员可编辑
        if (!oldQuestion.getUserId().equals(currentUser.getId()) && !userFeignClient.isAdmin(currentUser.getId())) {
            throw new BusinessException(MessageConstant.MISSING_ADMINISTRATOR_RIGHTS);
        }
        QuestionUpdateDTO questionUpdateDTO = new QuestionUpdateDTO();
        BeanUtils.copyProperties(questionEditDTO, questionUpdateDTO);
        questionService.updateQuestion(questionUpdateDTO);
        return Result.success();
    }

    @GetMapping("/get/vo/{id}")
    @ApiOperation("根据Id获取题目VO对象")
    public Result<QuestionVO> getQuestionVOById(@PathVariable long id) {
        if (id <= 0) {
            throw new ParameterException(MessageConstant.ERROR_PARAMETER + ":id不能小于0");
        }
        QuestionVO questionVO = questionService.getQuestionVO(id);
        return Result.success(questionVO);
    }

    @GetMapping("/get/{id}")
    @ApiOperation("管理员或当前用户，根据Id获取题目原对象")
    public Result<Question> getQuestionById(@PathVariable long id, HttpServletRequest httpServletRequest) {
        if (id <= 0) {
            throw new ParameterException(MessageConstant.ERROR_PARAMETER + ":id不能小于0");
        }
        Question oldQuestion = questionService.getById(id);
        if (oldQuestion == null) throw new BusinessException(MessageConstant.NO_EXISTS + ":question");
        UserVO currentUser = userFeignClient.getCurrentUser(httpServletRequest);
        // 仅本人或管理员可编辑
        if (!oldQuestion.getUserId().equals(currentUser.getId()) && !userFeignClient.isAdmin(currentUser.getId())) {
            throw new BusinessException(MessageConstant.MISSING_ADMINISTRATOR_RIGHTS);
        }
        return Result.success(questionService.getById(id));
    }


    /**
     * 分页获取列表（封装类）
     *
     * @param questionQueryDTO
     * @return
     */
    @PostMapping("/get/vo")
    @ApiOperation("获取题目VO列表")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<PageResult> listQuestionVOByPage(@RequestBody QuestionQueryDTO questionQueryDTO) {
        Integer pageSize = questionQueryDTO.getPageSize();
        // 限制爬虫
        if (pageSize > 20) throw new ParameterException(MessageConstant.ERROR_PARAMETER + ":pageSize过大");
        PageResult pageResult = questionService.getQuestionVOPage(questionQueryDTO);
        return Result.success(pageResult);
    }

    /**
     * 仅管理员可以查看列表
     */
    @PostMapping("/get")
    @ApiOperation("管理员获取题目列表")
    @JudgeEmpty(OperationTypeEnum.YES)
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public Result<PageResult> listQuestionByPage(@RequestBody QuestionQueryDTO questionQueryDTO) {
        Integer pageSize = questionQueryDTO.getPageSize();
        // 限制爬虫
        if (pageSize > 20) throw new ParameterException(MessageConstant.ERROR_PARAMETER + ":pageSize过大");
        PageResult pageResult = questionService.getQuestionPage(questionQueryDTO);
        return Result.success(pageResult);
    }

    @PostMapping("/questionSubmit/submit")
    @ApiOperation("提交题目记录")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<Long> doQuestionSubmit(@RequestBody QuestionSubmitAddDTO questionSubmitAddDTO, HttpServletRequest httpServletRequest) {
        Long questionSubmitId = questionSubmitService.doQuestionSubmit(questionSubmitAddDTO, httpServletRequest);
        return Result.success(questionSubmitId);
    }

    /**
     * 分页获取题目提交列表（除了管理员外，普通用户只能看到非答案、提交代码等公开信息）
     */
    @PostMapping("/questionSubmit/get/vo")
    @ApiOperation("分页获取题目提交列表")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<PageResult> listQuestionSubmitVOByPage(@RequestBody QuestionSubmitQueryDTO questionSubmitQueryDTO, HttpServletRequest httpServletRequest) {
        PageResult pageResult = questionSubmitService.getQuestionSubmitVOPage(questionSubmitQueryDTO, httpServletRequest);
        return Result.success(pageResult);
    }
}
